/**
 * 
 */
package EventHandling;

import Entities.Entity;
import Entities.EntityType;
import InstanceHandling.Dungeon;
import StringHandling.StringStripper;
import fightSequencing.Fight;
import fightSequencing.FightSequencer;

/**
 * @author Mark J Wood
 *
 */
public abstract class AbstractEventHandler implements EventHandler {

	private EventHandler nextEvent;
	protected StringStripper stripper = new StringStripper();
	protected Entity player;
	protected Entity mob;
	protected int indexOfEntity = -2;
	protected int eventAmount = 0;
	protected int eventTime = 0;
	protected int eventHealAmount = 0;
	protected String subjectName = "";
	protected String targetName = "";
	protected String abilityName = "";
	protected Fight localFight = null;
	protected int lineCount = 0;

	protected abstract String[] matchingEvent();
	protected abstract void handleHere(String anEvent);

	@Override
	public void setNextEvent(EventHandler handler) {
		this.nextEvent = handler;
	}// end method setNextEvent

	@Override
	public void processEvent(String anEvent) {
		boolean eventFound = false;

		if (this.matchingEvent().length == 0) {
			eventFound = true;
		} else {
			for (String match : this.matchingEvent()) {
				if (anEvent.indexOf(match) >= 0) {
					eventFound = true;
					break;
				}
			}
		}// end if

		if (eventFound) {
			this.handleHere(anEvent);
		} else {
			this.nextEvent.processEvent(anEvent);
		}//end if
	}// end method processEvent

	public static void handle(String anEvent) {
		// create the handler objects
		EventHandler combat = new CombatEventHandler();
		EventHandler heal = new HealEventHandler();
		EventHandler dead = new DeathEventHandler();
		EventHandler general = new GeneralEventHandler();

		combat.setNextEvent(heal);
		heal.setNextEvent(dead);
		dead.setNextEvent(general);

		combat.processEvent(anEvent);
	}


	public void setTheCorrectInstanceVariables(String eventType, String anEvent) {

		subjectName = stripper.stripCombatName(anEvent);
		eventTime = stripper.stripTime(anEvent);
		
		switch(eventType) {
		case "Combat" :
			abilityName = stripper.stripCombatAbility(anEvent);
			eventAmount = stripper.stripDamage(anEvent);
			targetName = stripper.stripCombatTargetName(anEvent);
			break;
		case "Heal" :
			eventAmount = stripper.stripHealAmount(anEvent);
			targetName = stripper.stripHealTargetName(anEvent);
			break;
		case "Death" :
			subjectName = stripper.stripDeathName(anEvent);
			break;
		}
	}
	
	public void populateCurrentSubject(Fight fight, String mob, String player) {
		Entity existingPlayer = fight.returnPlayerIfItExists(player);
		existingPlayer.addAbilityToDeck(abilityName, eventAmount);
	}

	public EntityType checkForType(String name) {
		EntityType result = null;
		if (Dungeon.checkIfBossExists(name) > -1) { 
			result = EntityType.BOSSMOB;	
		} else if (name.contains(" ") || name.matches("Ur-Thing")) {
			result = EntityType.ADDMOB;
		} else {
			result = EntityType.PLAYER;
		}
		return result;
	}
	
	public Fight findTheCorrectFight(String mobName) {
		Fight result = null;
		for (Fight f :FightSequencer.listOfCurrentFights) {
			if (f.getMob().getName().equalsIgnoreCase(mobName)) {
				result = f;
			} 
		}
		return result;
	}
	
	//For test purposes
	public Entity getPlayer() {
		return player;
	}
	public Entity getMob() {
		return mob;
	}
	public Fight getLocalFight() {
		return localFight;
	}
	
	
}
